package com.yry.security;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.junit.Test;
/**
 * 3、单向加密：消息摘要算法加密——HMAC
 * HMAC(Keyed-Hash Message Authentication Code)，含有密钥的散列函数算法
 * MD系列：HmacMD2、HmacMD4、HmacMD5
 * SHA系列：HmacSHA1、HmacSHA224、HmacSHA256、HmacSHA384、HmacSHA512
 * JDK:全部
 * BC：全部
 * 
 * @author Administrator
 *
 */
public class ImoocHmac {
	
	private String srcStr = "imooc security hmac";
	
	/**
	 * JDK hmac消息摘要算法；
	 */
	@Test
	public void jdkHmacMD5(){
		try {
			//初始化KeyGenerator;
			//KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacMD5");
			//产生密钥；
			//SecretKey  secretKey = keyGenerator.generateKey();
			//获得密钥
			//byte[] key = secretKey.getEncoded();
			
			//设置密钥；
			byte[] key = Hex.decodeHex(new char[]{'a','a','a','a','a','a','a','a','a','a'});
			
			
			//还原密钥
			SecretKey restoreSecretKey = new SecretKeySpec(key,"HmacMD5");
			//实例化MAC                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
			Mac mac = Mac.getInstance(restoreSecretKey.getAlgorithm());
			//初始化Mac
			mac.init(restoreSecretKey);
			//执行摘要；
			byte[] hmacMD5Bytes = mac.doFinal(srcStr.getBytes());
			//转成16进制字符串
			String hmacStr = Hex.encodeHexString(hmacMD5Bytes);
			System.out.println("JDK hmacMD5:"+hmacStr);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (DecoderException e) {
			e.printStackTrace();
		} 
	}
	
	/**
	 * bc的hmac算法应用
	 */
	@Test
	public void bcHmacMD5(){
		Digest digest = new MD5Digest();
		HMac hmac = new HMac(digest);
		
		byte[] initHexStr = org.bouncycastle.util.encoders.Hex.decode("aaaaaaaaaa");
		//初始化Mac；
		hmac.init(new KeyParameter(initHexStr));
		//更新Mac；
		hmac.update(srcStr.getBytes(), 0, srcStr.getBytes().length);
		//预设置摘要结果；
		byte[] hmacMD5Bytes = new byte[hmac.getMacSize()];
		hmac.doFinal(hmacMD5Bytes, 0);
		//将byte数组转成16进制；
		String hmacStr = org.bouncycastle.util.encoders.Hex.toHexString(hmacMD5Bytes);
		System.out.println(" BC hmacMD5:"+hmacStr);
		
	}
}
